﻿using System;
using System.Linq;
using Nomo.UnityCoreModule.UI;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace Nomo.UnityEditorModule
{
    internal static class EditorGraphicUtility
    {
        #region 更改射线检测

        [MenuItem(nameof(CoreModule.Nomo) + "/接收射线检测 √")]
        private static void RayCastAble()
        {
            foreach (var graphic in Selection.gameObjects.Select(e => e.GetComponent<Graphic>()).Where(e => e && !e.raycastTarget))
            {
                graphic.raycastTarget = true;
            }
        }

        [MenuItem(nameof(CoreModule.Nomo) + "/接收射线检测 ×")]
        private static void UnRayCastAble()
        {
            foreach (var graphic in Selection.gameObjects.Select(e => e.GetComponent<Graphic>()).Where(e => e && e.raycastTarget))
            {
                graphic.raycastTarget = false;
            }
        }

        #endregion

        #region 创建带有自定义图像组件的物体

        [MenuItem("GameObject/UI/Clear", true, 2003)]
        [MenuItem("GameObject/UI/Block", true, 2004)]
        [MenuItem("GameObject/UI/Shape", true, 2005)]
        private static bool IsGameObjectACanvasChild(MenuCommand command)
        {
            return command.context is GameObject gameObject && gameObject.GetComponentInParent<Canvas>();
        }

        [MenuItem("GameObject/UI/Clear", false, 2003)]
        private static void AddClear(MenuCommand menuCommand)
        {
            AddCustomUI(menuCommand, typeof(Clear));
        }

        [MenuItem("GameObject/UI/Block", false, 2004)]
        private static void AddBlock(MenuCommand menuCommand)
        {
            AddCustomUI(menuCommand, typeof(Block));
        }

        private static GameObject AddCustomUI(MenuCommand menuCommand, Type type)
        {
            if (menuCommand.context is GameObject gameObject && gameObject.GetComponentInParent<Canvas>())
            {
                var instance      = new GameObject(type.Name, type);
                var rectTransform = ((RectTransform) instance.transform);
                rectTransform.sizeDelta = Vector2.one * 100F;
                Undo.RegisterCreatedObjectUndo(instance, $"Create {instance.name}");
                GameObjectUtility.SetParentAndAlign(instance, gameObject);
                Selection.activeGameObject = instance;
                return instance;
            }

            Debug.LogError("创建失败，请在画布或其子物体上使用这个指令。");
            return default;
        }

        #endregion

        #region 图像组件替换

        #region TOTAL

        private static TNew GraphicReplacementPrivate<TOld, TNew>(TOld old) where TOld : Graphic where TNew : Graphic
        {
            var gameObject = old.gameObject;
            Undo.DestroyObjectImmediate(old);
            var @new = (TNew) gameObject.AddComponent(typeof(TNew));
            Undo.RegisterCreatedObjectUndo(@new, $"{nameof(GameObject.AddComponent)} : {typeof(TNew).Name}");
            return @new;
        }

        #endregion

        #region Image

        [MenuItem("CONTEXT/" + nameof(Image) + "/替换为" + nameof(RawImage))]
        private static void ImageToRawImage(MenuCommand menuCommand)
        {
            var       image   = (Image) menuCommand.context;
            Texture2D texture = default;
            var       sprite  = image.sprite;
            if (sprite)
            {
                var textureRect = sprite.textureRect;
                texture = new Texture2D((int) textureRect.x, (int) textureRect.y);
                texture.SetPixels(sprite.texture.GetPixels((int) textureRect.x, (int) textureRect.y, (int) textureRect.width, (int) textureRect.height));
                texture.Apply();
            }
            var rawImage = GraphicReplacementPrivate<Image, RawImage>(image);
            rawImage.texture = texture;
        }

        [MenuItem("CONTEXT/" + nameof(Image) + "/替换为" + nameof(Clear))]
        private static void ImageToClear(MenuCommand menuCommand)
        {
            GraphicReplacementPrivate<Image, Clear>((Image) menuCommand.context);
        }

        [MenuItem("CONTEXT/" + nameof(Image) + "/替换为" + nameof(Block))]
        private static void ImageToBlock(MenuCommand menuCommand)
        {
            var image = (Image) menuCommand.context;
            var color = image.color;
            var block = GraphicReplacementPrivate<Image, Block>(image);
            block.color = color;
        }

        #endregion

        #region RawImage

        [MenuItem("CONTEXT/" + nameof(RawImage) + "/替换为" + nameof(Image))]
        private static void RawImageToImage(MenuCommand menuCommand)
        {
            var    rawImage = (RawImage) menuCommand.context;
            Sprite sprite   = default;
            var    texture  = (Texture2D) rawImage.texture;
            if (texture)
            {
                sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.zero);
            }
            var image = GraphicReplacementPrivate<RawImage, Image>(rawImage);
            image.sprite = sprite;
        }

        [MenuItem("CONTEXT/" + nameof(RawImage) + "/替换为" + nameof(Clear))]
        private static void RawImageToClear(MenuCommand menuCommand)
        {
            GraphicReplacementPrivate<RawImage, Clear>((RawImage) menuCommand.context);
        }

        [MenuItem("CONTEXT/" + nameof(RawImage) + "/替换为" + nameof(Block))]
        private static void RawImageToBlock(MenuCommand menuCommand)
        {
            var rawImage = (RawImage) menuCommand.context;
            var color    = rawImage.color;
            var block    = GraphicReplacementPrivate<RawImage, Block>(rawImage);
            block.color = color;
        }

        #endregion

        #region Clear

        [MenuItem("CONTEXT/" + nameof(Clear) + "/替换为" + nameof(Image))]
        private static void ClearToImage(MenuCommand menuCommand)
        {
            GraphicReplacementPrivate<Clear, Image>((Clear) menuCommand.context);
        }

        [MenuItem("CONTEXT/" + nameof(Clear) + "/替换为" + nameof(RawImage))]
        private static void ClearToRawImage(MenuCommand menuCommand)
        {
            GraphicReplacementPrivate<Clear, RawImage>((Clear) menuCommand.context);
        }

        [MenuItem("CONTEXT/" + nameof(Clear) + "/替换为" + nameof(Block))]
        private static void ClearToBlock(MenuCommand menuCommand)
        {
            GraphicReplacementPrivate<Clear, Block>((Clear) menuCommand.context);
        }

        #endregion

        #region Block

        [MenuItem("CONTEXT/" + nameof(Block) + "/替换为" + nameof(Image))]
        private static void BlockToImage(MenuCommand menuCommand)
        {
            var block = (Block) menuCommand.context;
            var color = block.color;
            var image = GraphicReplacementPrivate<Block, Image>(block);
            image.color = color;
        }

        [MenuItem("CONTEXT/" + nameof(Block) + "/替换为" + nameof(RawImage))]
        private static void BlockToRawImage(MenuCommand menuCommand)
        {
            var block    = (Block) menuCommand.context;
            var color    = block.color;
            var rawImage = GraphicReplacementPrivate<Block, RawImage>(block);
            rawImage.color = color;
        }

        [MenuItem("CONTEXT/" + nameof(Block) + "/替换为" + nameof(Clear))]
        private static void BlockToClear(MenuCommand menuCommand)
        {
            GraphicReplacementPrivate<Block, Clear>((Block) menuCommand.context);
        }

        #endregion

        #endregion
    }
}
